#pragma once
#include <iostream>
#include <string>
#include <unordered_map>
#include "Connection.hpp"
#include "Epoller.hpp"

// 让TcpServer看到一个个的Conection对象
// 也就是让TcpServer对一个个的Conection对象进管理（符合先描述，在组织)
// Tcpserver: 对于就绪的事件进行通知
// 这个TCP server提供_connections管理工作
// 所以TcpServer就是一个Reactor（反应堆）
class Reactor // 事件派发器
{
    const static int gnum = 64;

public:
    Reactor():_isrunning(false)
    {
    }

    void AddConnection(int fd, uint32_t events, func_t recver, func_t sender, func_t excepter)
    {
        // 1.构建Connection——————————用户层面
        Connection *conn = new Connection(fd);
        conn->SetEvents(events);
        conn->Register(recver, sender, excepter); // 注册事件,如果事件就绪就执行这个任务
        conn->SetSelf(this);

        // 2. 向内核中设定对fd的关心————————内核层面
        _epoller.AddEvent(conn->Sockfd(), conn->Events());

        // 3. 向connections集合当中添加Connection对象————————用户层面，对每个链接做管理，用户后续找到就绪的fd
        _connections.insert(std::make_pair(conn->Sockfd(), conn));
    }

    void EnableReadWrite(int sockfd, bool readable, bool writeable)
    {
        uint32_t events = (readable ? EPOLLIN : 0) | (writeable ? EPOLLOUT : 0) | EPOLLET;
        if (connectionIsExists(sockfd))
        {
            // 1. 修改我们的connection关心的使事件
            _connections[sockfd]->SetEvents(events);

            // 2. 写透到内核中
            _epoller.ModEvent(sockfd, events);
        }
    }

    void RemoveConnection(int sockfd)
    {
        if (!connectionIsExists(sockfd)) return;
        // 1. 去掉epoll对该文件fd的关心
        _epoller.DelEvent(sockfd);
        // 2. 服务器关闭sockfd
        _connections[sockfd]->Close();
        // 3. 释放connection
        delete _connections[sockfd];
        _connections.erase(sockfd);
        LOG(DEBUG, "client close fd : %d\n", sockfd);
    }
    bool connectionIsExists(int fd)
    {
        auto iter = _connections.find(fd);
        return iter != _connections.end();
    }

    void LoopOnce(int timeout)
    {
        int n = _epoller.Wait(_revs, gnum, timeout);
        for (int i = 0; i < n; i++)
        {
            uint32_t events = _revs[i].events;
            int sockfd = _revs[i].data.fd;

            // 将异常错误统一处理
            if (events & EPOLLHUP)
                events |= (EPOLLIN | EPOLLOUT);
            if (events & EPOLLERR)
                events |= (EPOLLIN | EPOLLOUT);
            if (events & EPOLLIN)
            {
                if (connectionIsExists(sockfd) && (_connections[sockfd]->_recver != nullptr))
                {
                    _connections[sockfd]->_recver(_connections[sockfd]); // 进行回调
                }
            }
            if (events & EPOLLOUT)
            {
                if (connectionIsExists(sockfd) && (_connections[sockfd]->_sender != nullptr))
                {
                    _connections[sockfd]->_sender(_connections[sockfd]);
                }
            }
        }
    }

    // 事件派发核心函数
    void Dispatcher()
    {
        _isrunning = true;
        int timeout = -1;
        while (_isrunning)
        {
            LoopOnce(timeout);
            Debug();
        }
        _isrunning = false;
    }


    void Debug()
    {
        std::cout << "---------------------------------------" << std::endl;
        for (auto &connection : _connections)
        {
            std::cout << "fd : " << connection.second->Sockfd() << ", ";
            uint32_t events = connection.second->Events();
            if ((events & EPOLLIN) && (events & EPOLLET))
                std::cout << "EPOLLIN | EPOLLET, ";
            if ((events & EPOLLOUT) && (events & EPOLLET))
                std::cout << "EPOLLOUT | EPOLLET, ";
            std::cout << std::endl;
        }
        std::cout << "---------------------------------------" << std::endl;

    }
    ~Reactor()
    {
    }

private:
    std::unordered_map<int, Connection *> _connections; // 组织， int ： sockfd
    Epoller _epoller;

    struct epoll_event _revs[gnum];
    bool _isrunning;
};